package com.five.service.impl;

import com.five.basic.service.impl.BaseServiceImpl;
import com.five.constants.StatusConstant;
import com.five.dto.UpdateDto;
import com.five.exception.BusinessException;
import com.five.mapper.NovelMapper;
import com.five.mq.NovelSyncMessage;

import com.five.pojo.Novel;
import com.five.service.INovelService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;

@Service
@Slf4j
public class NovelServiceImpl extends BaseServiceImpl<Novel> implements INovelService {

    @Autowired
    private NovelMapper novelMapper;

    @Autowired
    private RocketMQTemplate rocketMQTemplate;


    @Override
    public Novel createBlankNovel(Long authorId) {
        if (null == authorId) {
            throw new BusinessException("无效的作者");
        }
//        Author author = UserServiceApi.selectById(authorId);
//        if(null == author){
//            throw new BusinessException("作者不存在");
//        }
        Novel novel = new Novel();
        novel.setAuthorId(authorId);
//        novel.setTitle(author.getUsername() + "的新书");
        novel.setTitle("新书");
        novel.setCategoryId(0L);
        novel.setStatus(StatusConstant.NovelStatus.NOVEL_PENDING);
        novel.setScore(0.0);
        novel.setWordCount(0L);
        novel.setRewardAmount(BigDecimal.ZERO);
        novel.setCommentCount(0);
        novel.setCollectCount(0);
        novel.setCreateTime(LocalDateTime.now());
        novel.setUpdateTime(LocalDateTime.now());
        novelMapper.add(novel);
        return novel;
    }

    @Override
    @Transactional
    public void add(Novel novel) {
        if (null == novel) {
            throw new BusinessException("无效小说");
        }
        if (null == novel.getAuthorId()) {
            throw new BusinessException("作者id不能为空");
        }
        if (null == novel.getTitle()) {
            throw new BusinessException("书名不能为空");
        }
        if (null == novel.getCategoryId()) {
            throw new BusinessException("分类不能为空");
        }
        novel.setStatus(StatusConstant.NovelStatus.NOVEL_PENDING);
        novel.setScore(0.0);
        novel.setWordCount(0L);
        novel.setRewardAmount(BigDecimal.ZERO);
        novel.setCommentCount(0);
        novel.setCollectCount(0);
        novel.setCreateTime(LocalDateTime.now());
        novel.setUpdateTime(LocalDateTime.now());
        novelMapper.add(novel);
        log.info("开始发送RocketMQ消息，novelId={}, operation={}", novel.getId(), "insert");
        NovelSyncMessage payload = NovelSyncMessage.builder()
                .novelId(novel.getId())
                .novel(novel)
                .operation("insert")
                .timestamp(System.currentTimeMillis())
                .build();
        rocketMQTemplate.sendOneWay("novel-topic",payload);
        log.info("RocketMQ消息发送成功，novelId={}", novel.getId());
    }

    @Override
    public boolean isExist(Long novelId) {
        return null != novelMapper.queryById(novelId);
    }

    @Override
    public List<Novel> queryNovelList(Long authorId) {
        if (null == authorId) {
            throw new BusinessException("无效的作者");
        }
        return novelMapper.queryNovels(authorId);
    }

    @Override
    public void updateWordCount(Long novelId, Integer wordCount) {
        if (null == novelId) {
            throw new BusinessException("无效的小说");
        }
        Novel novel = queryById(novelId);
        if (null == novel) {
            throw new BusinessException("小说不存在");
        }
        if (null == wordCount) {
            throw new BusinessException("字数不能为空");
        }
        novelMapper.updateWordCount(novelId, wordCount);
    }

    @Override
    public void updateStatus(UpdateDto dto) {
        // 1.校验
        if (null == dto) {
            throw new BusinessException("无效的更新参数");
        }
        Long novelId = dto.getId();
        Byte status = dto.getStatus();
        if (null == novelId || novelId <= 0) {
            throw new BusinessException("无效的小说");
        }
        if (null == status || !StatusConstant.isValidNovelStatus(status)) {
            throw new BusinessException("无效的小说状态");
        }
        // 2.更新小说状态
        Novel novel = queryById(novelId);
        if (null == novel) {
            throw new BusinessException("小说不存在");
        }
        novel.setUpdateTime(LocalDateTime.now());
        novelMapper.updateStatus(novelId, status);
    }

    @Override
    @Transactional
    public void update(Novel novel) {
        if (null == novel) {
            throw new BusinessException("无效小说");
        }
        if (null == novel.getId()) {
            throw new BusinessException("小说id不能为空");
        }
        if (null == novel.getTitle() || StringUtils.isBlank(novel.getTitle())) {
            throw new BusinessException("书名不能为空");
        }
        novel.setUpdateTime(LocalDateTime.now());
        novel.setStatus(StatusConstant.NovelStatus.NOVEL_PENDING);
        novelMapper.update(novel);
        NovelSyncMessage payload = NovelSyncMessage.builder()
                .novelId(novel.getId())
                .novel(novel)
                .operation("update")
                .timestamp(System.currentTimeMillis())
                .build();
        rocketMQTemplate.sendOneWay("novel-topic",payload);
    }
    @Transactional
    public void delete(Long novelId) {
        if (null == novelId || novelId <= 0) {
            throw new BusinessException("无效的小说");
        }
        if (!isExist(novelId)) {
            throw new BusinessException("小说不存在");
        }
        novelMapper.delete(novelId);
        NovelSyncMessage payload = NovelSyncMessage.builder()
                .novelId(novelId)
                .operation("delete")
                .timestamp(System.currentTimeMillis())
                .build();
        rocketMQTemplate.sendOneWay("novel-topic",payload);
    }

}